#include "ccd290_extract.h"

void extract_ccd_data_ob(char fname[], ccd290_config* cfg ) {

    unsigned short udata_E, udata_E_;
    unsigned short udata_F, udata_F_;
    unsigned short udata_G, udata_G_;
    unsigned short udata_H, udata_H_;

    // unsigned short data_E, data_F, data_G, data_H;
    unsigned short data_E=0, data_F=0, data_G=0, data_H=0;

    FILE *fb = fopen(fname,"rb");

/*    int num = LEN*2*4;	// total number of chars*/
/*    unsigned char *regs = (unsigned char*)malloc(sizeof(unsigned char)*num);*/
/*    fread(regs, sizeof(unsigned char), num, fb);*/

    int num = cfg->LEN*4;	// total number of chars
    unsigned short *regs = (unsigned short*)malloc(sizeof(unsigned short)*num);
    int num_chk = fread(regs, sizeof(unsigned short), num, fb);

    if( num_chk != num ){
    	printf("Error in reading binary data: %s\n", fname);
    }

    fclose(fb);

    unsigned short *ch_E, *ch_F, *ch_G, *ch_H;
    ch_E = (unsigned short*)malloc(sizeof(unsigned short)*cfg->LEN);
    ch_F = (unsigned short*)malloc(sizeof(unsigned short)*cfg->LEN);
    ch_G = (unsigned short*)malloc(sizeof(unsigned short)*cfg->LEN);
    ch_H = (unsigned short*)malloc(sizeof(unsigned short)*cfg->LEN);


    int i,j;
    int cnt=0;
    int imin = (940*cfg->N_COL*cfg->SAMP_NUM_PER_REG*4);    // for debug
    for(i=0; i<num; i+=4) {

        udata_E = regs[i+0];
        udata_F = regs[i+1];
        udata_G = regs[i+2];
        udata_H = regs[i+3];

        j = i+4;
        if( j < num ) {

            udata_E_ = regs[j+0];
            udata_F_ = regs[j+1];
            udata_G_ = regs[j+2];
            udata_H_ = regs[j+3];

        //	shift 4-bits to recover original LTC2271 AD outputs
            // unsigned short E, F, G, H;
            unsigned short E, F, G, H;
            E = ((udata_E & 0x0fff) << 4) | ((udata_E_ & 0xf000) >> 12);
            F = ((udata_F & 0x0fff) << 4) | ((udata_F_ & 0xf000) >> 12);
            G = ((udata_G & 0x0fff) << 4) | ((udata_G_ & 0xf000) >> 12);
            H = ((udata_H & 0x0fff) << 4) | ((udata_H_ & 0xf000) >> 12);

            ch_E[cnt] = E;
            ch_F[cnt] = F;
            ch_G[cnt] = G;
            ch_H[cnt] = H;

            if( i>imin && i<imin+1*cfg->N_COL*cfg->SAMP_NUM_PER_REG*4){
            	// printf(" %6d %6d %6d %6d 0x%04x 0x%04x 0x%04x 0x%04x\n", data_E, data_F, data_G, data_H, E, F, G, H);
                printf("%6u %6u %6u %6u 0x%04x 0x%04x 0x%04x 0x%04x\n", data_E, data_F, data_G, data_H, E, F, G, H);
            }

            cnt++;
            
        }
    }
    
//	CDS
    unsigned short *ccd = (unsigned short*)malloc(sizeof(unsigned short)*cfg->N_ROW*cfg->N_COL*4);
    
    for(i=0; i<cfg->N_ROW*cfg->N_COL*4; i++) 
        ccd[i] = 0;

    //  for CCD290@333KHz

    double size1 = 6, size2 = 6;
	uint offset = 10;
	
    uint E_idx1 = 2;
    uint E_idx2 = 7;
    uint E_idx3 = 11;
    uint E_idx4 = 16;

    uint F_idx1 = 2;
    uint F_idx2 = 7;
    uint F_idx3 = 11;
    uint F_idx4 = 16;
    
    uint G_idx1 = 2;
    uint G_idx2 = 7;
    uint G_idx3 = 11;
    uint G_idx4 = 16;
    
    uint H_idx1 = 2;
    uint H_idx2 = 7;
    uint H_idx3 = 11;
    uint H_idx4 = 16;
    
    //  for CCD290@1MHz
    // double size1 = 2, size2 = 2; 
	// uint offset = 6;
	
    // uint E_idx1 = 0;
    // uint E_idx2 = 1;
    // uint E_idx3 = 3;
    // uint E_idx4 = 4;

    // uint F_idx1 = 0;
    // uint F_idx2 = 1;
    // uint F_idx3 = 3;
    // uint F_idx4 = 4;
    
    // uint G_idx1 = 0;
    // uint G_idx2 = 1;
    // uint G_idx3 = 3;
    // uint G_idx4 = 4;
    
    // uint H_idx1 = 0;
    // uint H_idx2 = 1;
    // uint H_idx3 = 3;
    // uint H_idx4 = 4;

//	DEBUG
/*	printf("SAMP_PER_REG = %d\n", SAMP_PER_REG);*/
/*	exit(0);*/

    
    int row=0,col=0;
    int idx;
    for(idx=offset; idx<cfg->LEN-4; idx+=cfg->SAMP_NUM_PER_REG) {

        int idxE = row*cfg->N_COL*2 + col;
        int idxF = row*cfg->N_COL*2 + (cfg->N_COL*2-col-1);
        int idxG = (cfg->N_ROW*2-row-1)*cfg->N_COL*2 + col;
        int idxH = (cfg->N_ROW*2-row-1)*cfg->N_COL*2 + (cfg->N_COL*2-col-1);
        
        int sumE1=0, sumE2=0;
        int sumF1=0, sumF2=0;
        int sumG1=0, sumG2=0;
        int sumH1=0, sumH2=0;

		int cnt;
		// for( cnt=E_idx1; cnt<=E_idx2; cnt++ ) sumE1 += (int)ch_E[idx+cnt];
		// for( cnt=E_idx3; cnt<=E_idx4; cnt++ ) sumE2 += (int)ch_E[idx+cnt];

		// for( cnt=F_idx1; cnt<=F_idx2; cnt++ ) sumF1 += (int)ch_F[idx+cnt];
		// for( cnt=F_idx3; cnt<=F_idx4; cnt++ ) sumF2 += (int)ch_F[idx+cnt];

		// for( cnt=G_idx1; cnt<=G_idx2; cnt++ ) sumG1 += (int)ch_G[idx+cnt];
		// for( cnt=G_idx3; cnt<=G_idx4; cnt++ ) sumG2 += (int)ch_G[idx+cnt];

		// for( cnt=H_idx1; cnt<=H_idx2; cnt++ ) sumH1 += (int)ch_H[idx+cnt];
		// for( cnt=H_idx3; cnt<=H_idx4; cnt++ ) sumH2 += (int)ch_H[idx+cnt];

		for( cnt=E_idx1; cnt<=E_idx2; cnt++ ) sumE1 += ch_E[idx+cnt];
		for( cnt=E_idx3; cnt<=E_idx4; cnt++ ) sumE2 += ch_E[idx+cnt];

		for( cnt=F_idx1; cnt<=F_idx2; cnt++ ) sumF1 += ch_F[idx+cnt];
		for( cnt=F_idx3; cnt<=F_idx4; cnt++ ) sumF2 += ch_F[idx+cnt];

		for( cnt=G_idx1; cnt<=G_idx2; cnt++ ) sumG1 += ch_G[idx+cnt];
		for( cnt=G_idx3; cnt<=G_idx4; cnt++ ) sumG2 += ch_G[idx+cnt];

		for( cnt=H_idx1; cnt<=H_idx2; cnt++ ) sumH1 += ch_H[idx+cnt];
		for( cnt=H_idx3; cnt<=H_idx4; cnt++ ) sumH2 += ch_H[idx+cnt];

        ccd[idxE] = (unsigned short)( ( sumE1/size1 - sumE2/size2 ) );
        ccd[idxF] = (unsigned short)( ( sumF1/size1 - sumF2/size2 ) );
        ccd[idxG] = (unsigned short)( ( sumG1/size1 - sumG2/size2 ) );
        ccd[idxH] = (unsigned short)( ( sumH1/size1 - sumH2/size2 ) );

    	col++;  // 必须先+1,然后再进行判断
        if(col >= cfg->N_COL) {
            col -= cfg->N_COL;
            row++;
        }
    }



//	===================================================
    fitsfile *fptr;
    int status;
    long fpixel = 1, naxis = 2, nelements, exposure;
    long naxes[2] = {cfg->N_COL*2, cfg->N_ROW*2}; // image is 300 pixel wide by 200 rows
/*    long naxes[2] = {N_ROW*2, N_COL*2}; // image is 300 pixel wide by 200 rows*/
    

    status = 0;
    fits_create_file(&fptr, "tmp_ob.fits", &status); /* create new file */

    /*Create the primary array image (16-bit short uinteger pixels) */
    /*	fits_create_img(fptr, SHORT_IMG, naxis, naxes, &status);*/
    fits_create_img(fptr, USHORT_IMG, naxis, naxes, &status);

    /*Write a keyword; must pass the ADDRESS of the value */
    exposure = 1500.;
    fits_update_key(fptr, TLONG, "EXPOSURE", &exposure, "Total Exposure Time", &status);
    nelements = naxes[0] * naxes[1];

    /* Write the array of integers to the image */
    /*	fits_write_img(fptr, TSHORT, fpixel, nelements, ccd, &status);*/
    fits_write_img(fptr, TUSHORT, fpixel, nelements, ccd, &status);

    fits_close_file(fptr, &status);

    fits_report_error(stderr, status);
//	===================================================

    free(ch_E);
    free(ch_F);
    free(ch_G);
    free(ch_H);

    free(regs);
    free(ccd);
}


